/*
 * > /*
>  * INSANE - Interactive Structural Analysis Environment
>  *
>  * Copyright (C) 2003-2004
>  * Universidade Federal de Minas Gerais
>  * Escola de Engenharia
>  * Departamento de Engenharia de Estruturas
>  *
>  * Author's email :     insane@dees.ufmg.br
>  * Author's Website :   http://www.dees.ufmg.br/insane
>  *
>  * This program is free software; you can redistribute it and/or
>  * modify it under the terms of the GNU General Public License
>  * as published by the Free Software Foundation; either version 2
>  * of the License, or any later version.
>  *
>  * This program is distributed in the hope that it will be useful,
>  * but WITHOUT ANY WARRANTY; without even the implied warranty of
>  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>  * GNU General Public License for more details.
>  *
>  * You should have received a copy of the GNU General Public License
>  * along with this program; if not, write to the Free Software
>  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-
> 1307, USA.
 *
 */
package br.ufmg.dees.insane.ui.rich.learn.learn_view;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.WindowConstants;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeSelectionModel;

import br.ufmg.dees.insane.model.disc.driver.StructuralMech;
import br.ufmg.dees.insane.model.disc.element.Element;
import br.ufmg.dees.insane.model.disc.element.FrameElement;
import br.ufmg.dees.insane.model.disc.element.ParametricElement;
import br.ufmg.dees.insane.model.disc.fem.FemModel;
import br.ufmg.dees.insane.ui.rich.learn.learn_controller.Controller;
import br.ufmg.dees.insane.ui.rich.learn.learn_view.displacements_view.DisplacementsView;
import br.ufmg.dees.insane.ui.rich.learn.learn_view.displacements_view.FrameDisplacementsView;
import br.ufmg.dees.insane.ui.rich.learn.learn_view.element_view.ElementView;
import br.ufmg.dees.insane.ui.rich.learn.learn_view.equation_view.EquationsView;
import br.ufmg.dees.insane.ui.rich.learn.learn_view.model_solution_view.ModelSolutionView;
import br.ufmg.dees.insane.ui.rich.learn.learn_view.model_view.ModelView;
import br.ufmg.dees.insane.ui.rich.learn.learn_view.strain_view.FrameStrainView;
import br.ufmg.dees.insane.ui.rich.learn.learn_view.strain_view.StrainView;
import br.ufmg.dees.insane.ui.rich.learn.learn_view.stress_view.FrameStressView;
import br.ufmg.dees.insane.ui.rich.learn.learn_view.stress_view.StressView;

/**
*
* @author Moreira, Renata & Pitangueira, Roque
* @since May 2005
*/
public class LearnInterface extends JFrame implements ActionListener, TreeSelectionListener {
	    
	    /**
		 * Comment for <code>serialVersionUID</code>
		 */
		private static final long serialVersionUID = 1L;
		private IView view;
		private FemModel model;
	   // private IView view = new LearnView(this, this.getModel());
	    
	    private InsaneProperties properties = new InsaneProperties();
		
	    //Main panels
	    private JPanel drawArea = new JPanel();
		private DefaultMutableTreeNode top = new DefaultMutableTreeNode("Targets");

	    private JTree tree = new JTree(top);
	    private JScrollPane treeView = new JScrollPane(tree);
		private JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, treeView, drawArea);
		
		//Handler for Console events
		private ConsoleHandler consoleHandler = new ConsoleHandler(this);
		
	    //Menu
	    private JMenuBar menuBar = new JMenuBar();
	    
	    //Tools
	    
	    private JPanel toolPanel = new JPanel();
	  
		//In-Out Panel
		private JPanel inOutBar = new JPanel(new BorderLayout(6,0));
	    private Console console = new Console(this);
			
	    private JPanel statusBar = new JPanel();
	    
	    private JTextField messageField = new JTextField(21);
	    private JTextField coordField = new JTextField("Coords :",1);
	    private JPanel state = new JPanel();
	    
//	*****************************************************************************
		
	    /**
	     * The constructor method. <br>
	     * Calls the init() method throwing an exception.
	     */
	    public LearnInterface(FemModel m) {
	    	this.model = m;
	    	view = new LearnView(this, m);
	    	//((LearnView)this.view).getController().setModel(model);
	        try {
	            init();
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
			SplashScreen.getInstance().finish();
	    }
		
//	*****************************************************************************
		
	  
	    
	    /**
	     * It's called by the constructor. <br>
	     * Sets Panels, components and provides a window listener.
	     */
	    public void init() throws Exception {
	        
			
	        this.setTitle("INSANE " + this.getProperties().getVersion());
			this.setSize(new Dimension(800, 640));
			this.setExtendedState(JFrame.MAXIMIZED_BOTH);
			
			this.messageField.setText("Escola de Engenharia da UFMG");
			
			this.getContentPane().setLayout(new BorderLayout());
			this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
	        this.addWindowListener(new WindowAdapter() {
	            public void windowClosing(WindowEvent e) {
	                view.exit();
	            }
	        } );
	        Image ico = Toolkit.getDefaultToolkit().getImage(ClassLoader.getSystemResource("br/ufmg/dees/insane/images/Insane64.gif"));
	        this.setIconImage(ico);
	        
			toolPanel.setLayout(new BoxLayout(toolPanel, BoxLayout.X_AXIS));
	        this.getContentPane().add(toolPanel, BorderLayout.NORTH);
	        this.setToolPanel(toolPanel);
	        
	        splitPane.setOneTouchExpandable(true);
	        splitPane.setDividerLocation(0);
	        splitPane.setBorder(BorderFactory.createEmptyBorder(2,3,1,3));
	        this.setSplitPane(splitPane);
			
	        drawArea.setLayout(new BorderLayout());
	        drawArea.setBorder(BorderFactory.createEmptyBorder(0,0,0,3));
	        this.setDrawPanel(drawArea);
			
	        this.createNodes(top);
	        tree.putClientProperty("JTree.lineStyle", "Angled");
	        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
			tree.setExpandsSelectedPaths(true);
	        tree.addTreeSelectionListener(this);
	        this.setTree(tree);
	        
	        this.getContentPane().add(splitPane, BorderLayout.CENTER);
	                
	        this.setJMenuBar(menuBar);
	        this.setMenuPanel(menuBar);
	        
			//Setting status bar
	        
	        statusBar.setLayout(new BoxLayout(statusBar, BoxLayout.X_AXIS));
			
	        messageField.setEditable(false);
			messageField.setBorder(BorderFactory.createEmptyBorder(2,3,1,3));
	        coordField.setEditable(false);
			coordField.setBorder(BorderFactory.createEmptyBorder(2,3,1,3));
	        state.setLayout(new GridLayout(1,3,1,1));
	        this.setStatePanel(state);
	        
	        statusBar.add(coordField);
	        statusBar.add(state);
			statusBar.add(messageField);
	        
			console.addListener(consoleHandler);
			this.setConsolePanel(console);
			
			inOutBar.add(BorderLayout.SOUTH, statusBar);
			inOutBar.add(BorderLayout.NORTH, console);
			
	        this.getContentPane().add(inOutBar,BorderLayout.SOUTH);
	        
			this.setCoord("" + 0.0, "" + 0.0);
		
	        setInitialInterface();
	        
	    }
	    
//	*****************************************************************************
		
		
		
	    /**
	     * Returns the current model.
	     * @return The current model.
	     */
	    public FemModel getModel() {
	        return model;
	    }	    
		
		/** Sets the Model.
		*@param mdl The Model to be set.
		*/
	    public void setModel(FemModel mdl) {
	        ((Controller)this.view.getController()).setDriver(new StructuralMech());
	        ((Controller)this.view.getController()).getDriver().setFemModel(mdl);
	        ((Controller)this.view.getController()).setModel(mdl);
	        ((LearnView)this.view).getController().setModel(model);
	        ((LearnView)this.view).getDrawingArea().setZoom(((LearnViewState)this.view.getViewState()).getLimits());
	        ((LearnView)this.view).getDrawingArea().setPrecision(((LearnViewState)this.view.getViewState()).getPrecision());
	        ((LearnView)this.view).getDrawingArea().setSnap(((LearnViewState)this.view.getViewState()).isSnapOn());
	        ((LearnView)this.view).getDrawingArea().setGridColor(((LearnViewState)this.view.getViewState()).gridColor);
	        ((LearnView)this.view).getDrawingArea().setGrid(((LearnViewState)this.view.getViewState()).isGridOn());
	        ((LearnView)this.view).getDrawingArea().setGridIncs(((LearnViewState)this.view.getViewState()).getGridXInc(),
	                		((LearnViewState)this.view.getViewState()).getGridYInc());
	        ((LearnView)this.view).getDrawingArea().setBackground(((LearnViewState)this.view.getViewState()).bgcolor);
	        this.view.init();
	    }
		
		/** Return the SplitPane.
		*@return The SplitPane.
		*/
	    public JSplitPane getSplitPane() {
	        return splitPane;
	    }
	    public void setSplitPane(JSplitPane jsp) {
	        splitPane =jsp;
	    }
		
		/** Return the current ModelState.
		*@return The current ModelState.
		*/
	    public IView getView() {
	        return this.view;
	    }   
		
		/** Returns the properties.
		*@return The properties.
		*/
	    public InsaneProperties getProperties() {
	        return properties;
	    }
	    
		/** Sets the initial Interface. */
	    public void setInitialInterface() {
			
	    }
	    	   		
		
//	*****************************************************************************
		
	    /**
	     * Sets the Status Bar coord text.
	     * @param x The first "X" coordinate.
	     * @param y The second "Y" coordinate.
	     */
	    public void setCoord(String x, String y) {
	        this.coordField.setText("Coords: " + x + ", " + y);
	    }
	    
//	*****************************************************************************
		
	    /**
	     * Sets the Status Bar message.
	     * @param str The text to be shown
	     */
	    public void setMessage(String str) {
	        this.messageField.setText(str);
		}
		
//	*****************************************************************************
		
	    /**
	     * Appends a message to the output panel.
	     * @param str The message to be appended.
	     */
	    public void addOutputText(String str) {
	        this.console.addOutputText(str);
		}
	    
	    
//	*****************************************************************************
		
		/** Method which executes the desired action to each command.*/
	    public void actionPerformed(ActionEvent evt) {
	        CommandHolder obj = (CommandHolder)evt.getSource();
			obj.getCommand().execute();
	    }
	    
//	*****************************************************************************
		
		/** Creates the nodes of the tree.
		* @param top The root of the tree.
		*/
	    public void createNodes(DefaultMutableTreeNode top) {
	        DefaultMutableTreeNode folder = null;
	        DefaultMutableTreeNode child = null;
			
			folder = new DefaultMutableTreeNode("Interactive Processor");
			top.add(folder);
			
			child = new DefaultMutableTreeNode("Equations");
			folder.add(child);
			
			child = new DefaultMutableTreeNode("Displacements");
			folder.add(child);
			
			child = new DefaultMutableTreeNode("StrainXDisplacements");
			folder.add(child);
			
			child = new DefaultMutableTreeNode("StressXStrain");
			folder.add(child);
			
			child = new DefaultMutableTreeNode("Element Equilibrium");
			folder.add(child);
	        
			child = new DefaultMutableTreeNode("Model Equilibrium");
			folder.add(child);
			
			child = new DefaultMutableTreeNode("Model Solution");
			folder.add(child);
			
			child = new DefaultMutableTreeNode("Element Solution");
			folder.add(child);
			
	    }
	    
	    /** Method which executes the desired action to selected node of the tree.*/
	    public void valueChanged(TreeSelectionEvent e) {
	        DefaultMutableTreeNode node = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
	        
	        if (node == null) return;
	        
			Object nodeObj = node.getUserObject();
	        if (node.isLeaf()) {
	        	
	        	if (nodeObj.equals("Equations")) {
	        	    FemModel m = this.view.getController().getModel();
	        		this.view = new EquationsView(this, model);
	        		this.setModel(m);
	        		((Controller)this.view.getController()).getDriver().zeroNodeEquations();
	        		
				}else if (nodeObj.equals("Displacements")) {
					FemModel m = this.view.getController().getModel();
					Element elm = (Element)m.getElementsList().get(0);
					if (elm instanceof FrameElement){
						this.view = new FrameDisplacementsView(this, model);
					    this.setModel(m);
					    //this.view.getDrawingArea().setClickedCommand(new SelectCommand(this));
					}
					if (elm instanceof ParametricElement){
						this.view = new DisplacementsView(this, model);
						this.setModel(m);
						//this.view.getDrawingArea().setClickedCommand(new SelectCommand(this));
					}
					
				}else if (nodeObj.equals("StrainXDisplacements")) {
					FemModel m = this.view.getController().getModel();
					Element elm = (Element)m.getElementsList().get(0);
					
					if (elm instanceof FrameElement){
						this.view = new FrameStrainView(this, model);
					    this.setModel(m);
					    //this.view.getDrawingArea().setClickedCommand(new SelectCommand(this));
					}
					if (elm instanceof ParametricElement){
						this.view = new StrainView(this, model);
					    this.setModel(m);
						//this.view.getDrawingArea().setClickedCommand(new SelectCommand(this));
					}
                    
					
				}else if (nodeObj.equals("StressXStrain")) {
					FemModel m = this.view.getController().getModel();
					Element elm = (Element)m.getElementsList().get(0);
					if (elm instanceof FrameElement){
						this.view = new FrameStressView(this, model);
					    this.setModel(m);
					    //this.view.getDrawingArea().setClickedCommand(new SelectCommand(this));
					}
					if (elm instanceof ParametricElement){
						this.view = new StressView(this, model);
					    this.setModel(m);
						//this.view.getDrawingArea().setClickedCommand(new SelectCommand(this));
					}
				}else if (nodeObj.equals("Element Equilibrium")) {
					FemModel m = this.view.getController().getModel();
				    this.view = new ElementView(this, model);
				    this.setModel(m);
					
				}else if (nodeObj.equals("Model Equilibrium")) {
					FemModel m = this.view.getController().getModel();
				    this.view = new ModelView(this, model);
				    this.setModel(m);
					
				}else if (nodeObj.equals("Model Solution")) {
					FemModel m = this.view.getController().getModel();
				    this.view = new ModelSolutionView(this, model);
				    this.setModel(m);
					
				}else if (nodeObj.equals("Element Solution")) {
					FemModel m = this.view.getController().getModel();
					Element elm = (Element)m.getElementsList().get(0);
				    //this.view = new DisplacementsView(this);
				    //this.setModel(m);
				    
				    if (elm instanceof FrameElement){
						this.view = new FrameDisplacementsView(this, model);
					    this.setModel(m);
					    //this.view.getDrawingArea().setClickedCommand(new SelectCommand(this));
					}
					if (elm instanceof ParametricElement){
						this.view = new DisplacementsView(this, model);
					    this.setModel(m);
						//this.view.getDrawingArea().setClickedCommand(new SelectCommand(this));
					}
				}
	        }	
				
	    }
	    
		
//	*****************************************************************************
		
		/** Returns the Console of this Interface.
		*@return The Console of this Interface.
		*/
		public void setConsolePanel(Console cp) {
			console=cp;
		}
		
		public void setMenuPanel(JMenuBar mb) {
			menuBar=mb;
		}
		
		public void setToolPanel(JPanel tp) {
			toolPanel=tp;
		}
		
		public void setDrawPanel(JPanel dp) {
			drawArea=dp;
		}
		
		public void setStatePanel(JPanel sp) {
			state=sp;
		}
		
		public void setTree(JTree t) {
			tree=t;
		}
		
		
		public Console getConsolePanel() {
			return this.console;
		}
		
		public JMenuBar getMenuPanel() {
			return this.menuBar;
		}
		
		public JPanel getToolPanel() {
			return this.toolPanel;
		}
		
		public JPanel getDrawPanel() {
			return this.drawArea;
		}
		
		public JPanel getStatePanel() {
			return this.state;
		}
		
		public JTree getTree() {
			return this.tree;
		}
		
		/** Returns the ConsoleHandler of this Interface.
		*@return The ConsoleHandler of this Interface.
		*/
		public ConsoleHandler getConsoleHandler() {
			return consoleHandler;
		}
		
//	*****************************************************************************
		
		/** Sets the Interface to the specified tree node.
		*@param a A flag representing the desired tree node (see model.ModelState).
		*@see model.ModelState
		*/
		public void setToTreeNode(int a) {
			
		}
		
		 /**
	     * Closes the current model and returns true if successfull.
	     * @return   A boolean if the current model was closed or not.
	     */
	    public boolean closeModel() {
	        
			boolean ret = true;
			FemModel model = ((Controller)this.getView().getController()).getModel();
	        if (model != null) {
	            int value = 10;
	            value = JOptionPane.showConfirmDialog(this,
	            "Would you like to save " + this.getView().getViewState().getName()+ " ?", "Warning",
	            JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
	            if (value == JOptionPane.YES_OPTION){
	                //saveFileCmd.execute();
	            }else if(value == JOptionPane.CANCEL_OPTION){
	                ret = false;
	            }
	        }
	        if (ret) {
	            model = null;
	            this.setMessage(" ");
	            this.setCoord(" ", " ");
	            this.getView().init();
	        }
	        return ret;
	    }
		
}
	



